#ifndef URISC_BETA_H_
#define URISC_BETA_H_


#include <iostream>
#include <unistd.h>	

#include <vector>
#include <fstream>
#include <sstream>


using namespace std;


typedef unsigned short int u16bits;
typedef unsigned char u8bits;

int charToHex(char _ch);
u16bits strToU16(string _inStr);
u16bits estende8(unsigned char _inbits);
u16bits estende12(u16bits _inbits);
u16bits estende11(u16bits _inbits);

class RegFile{
public:
	RegFile();
	~RegFile();
	void enable(u16bits r_addr_1, u16bits r_addr_2, u16bits &r_data_1, u16bits &r_data_2);                                  // R
	void enable(u16bits r_addr_1, u16bits r_addr_2, u16bits w_addr, u16bits &r_data_1, u16bits &r_data_2, u16bits w_data);  // RW
	void enable(u16bits w_addr, u16bits w_data);                                                                            // W
private:
	u16bits *_regFie;	
};

class MemRAM{
public:
	MemRAM();
	~MemRAM();
	void enableRead(u16bits addr, u16bits &memData);
	void enableWrite(u16bits addr, u16bits memData);	
	void loadProg(ifstream &inFile);
private:
	u16bits *_memRAM;	
};


class uRISC_Beta{
public:
	uRISC_Beta(ifstream &inFile);
	void ciclo_IF(void);
	void ciclo_ID(void);
	void ciclo_ExMem(void);
	void ciclo_WB(void);

	u16bits getRegFile(u8bits reg);   
	u16bits getMemRAM(u16bits addr);
	u16bits getRegA(void){ return regA; };   
	u16bits getRegB(void){ return regB; };   
	u16bits getRegIR(void){ return regIR; }; 
	u16bits getRegMR(void){ return  regMR; };
	u16bits getRegALU(void){ return regALU; };
	u16bits getRegPC(void){ return regPC; };
	u16bits getRegFlags(void){ return regFlags; };	
	int getViewOp(void){ return viewOpALU; };
private:	
	//auxiliar para debug
	int viewOpALU;
	//Data Path
	RegFile regFile;   //Arquivo de registradores
	MemRAM  memRAM;    //Memoria de programa e dados
	u16bits regA;   //registrador de entrada A da ALU
	u16bits regB;   //registrador de entrada B da ALU
	u16bits regIR;  //registrador de Instrucao
	u16bits regMR;  //registrador de Memoria de Dado da memoria
	u16bits regALU; //registrador de saida da ALU
	u16bits regPC;  //registrador PC
	u16bits regFlags; //registrador de Flags
	//sinais de controle
	enum _execution_code { F1, F2, F3, F4_0, F4_1, F5, F6_0, F6_1, F7_0, F7_1 } execution_code;
	//                      0   1   2     3     4   5     6     7     8     9
};


#endif /*URISC_BETA_H_*/
